#!/bin/bash


export PS4='+ {$LINENO:${FUNCNAME[0]}} '

set_option ()
{
    read -r SUNDAY EN_US MONDAY ZH_CN <<< "true true false false"
    # getopt 有版本区别 最好用增强版（getopt -T;echo $? 输出为4） getopt 命令一般在 util-linux 包中  rpm -ql util-linux | grep getopt
    # getopt 会自己判断无效选项，所以无需自己判断了
    # 使用 getopt 生成一个重新排列的参数列表
    TEMP=`getopt -o hmsz --long sunday,monday,zh,help -n "${SCRIPT_NAME}:L${BASH_LINENO[0]}:getopt" -- "$@"`
    if [ $? != 0 ]; then
        echo "Terminating..." >&2
        exit 1
    fi

    # 重新排列参数
    eval set -- "$TEMP"

    # 处理选项
    # 当为::时，才表示可选的，且argument必须紧贴选项，例如-carg而不能是-c arg，--clong=arg而不能是--clong arg，所以逻辑可优化
    while true ; do
        case "$1" in
            -s|--sunday) SUNDAY="true" ; MONDAY="false" ; shift ;;
            -m|--monday) MONDAY="true" ; SUNDAY="false" ; shift ;;
            -z|--zh) ZH_CN="true" ; EN_US="false" ; shift ;;
            -h|--help)
                echo "Usage: ${0##*/} [-s, --sunday|-m, --monday|-z, --zh|-h, --help]"
                exit 0
                ;;
            --) shift ; break ;;
        esac
    done

    # 处理剩余的参数
    #echo "--${@}--"
    #shift $[$OPTIND -1 ]
    #echo "--${@}--"

    # 返回处理后的参数，不包括选项
    declare -g ARGS_LEFT=("${@}")
    return 0
}

next_N_day ()
{
    date -d"${1} ${2} day" +%F
}

out_month ()
{
    local sdate="${1}"
    local edate="$(next_N_day ${1} 41)"
    while [[ "$sdate" < "$edate" || "$sdate" == "$edate" ]]; do
        month_year=$(date -d "$sdate" +'%Y %m')
        echo "$month_year"

        next_month=$(date -d "$sdate + 1 month" +'%Y-%m-01')
        if [[ "$next_month" > "$edate" ]]; then
            break
        fi

        sdate="$next_month"
    done
}

# 函数：打印日历头部
print_header() {
    $SUNDAY && $EN_US && printf "Su Mo Tu We Th Fr Sa\n"
    $SUNDAY && $ZH_CN && printf "日 一 二 三 四 五 六\n"
    $MONDAY && $ZH_CN && printf "一 二 三 四 五 六 日\n"
    $MONDAY && $EN_US && printf "Mo Tu We Th Fr Sa Su\n"
}

# 函数：打印空格，用于对齐
print_spaces_before() {
    # 补前置空格
#    for ((i=1; i<=$1; i++)); do
#        printf "   "
#    done
    printf '%*.0s' $(($1*3)) ' '
}

print_spaces_after() {
    # 补前置空格
#    for ((i=1; i<=$(($1-1)); i++)); do
#        printf "   "
#    done
    print_spaces_before $(($1-1))
    printf "  \n"
}

# 函数：打印月份
print_month() {
    local year=$1
    local month=$2
    local first_day=$(date -d "$year-$month-01" '+%w') # 1代表星期一，0代表星期日
    local days_in_month=$(date -d "$year-$month-01 +1 month -1 day" '+%d')
    local last_day_week=$(date -d "$year-$month-$days_in_month" '+%w')

    today=$(date +%F)
    preview=$(next_N_day ${medium_date} 9)
    start_date=${ysVerDate[${major_version}.${minor_version}]:11:10}
    medium_date=${ysVerDate[${major_version}.${minor_version}]:22:10}
    end_date=$(next_N_day ${medium_date} 21)
    
    $EN_US && title=$(LANG=C date -d"$year-$month-01" +'%B %Y')
    $ZH_CN && title=$(LANG=zh_CN.utf8 date -d"$year-$month-01" +'%B %Y')
    padding=$(( (20 -${#title}) / 2 ))
    printf "%*s%s%*s\n" $((20-padding-${#title})) " " "$title" $padding " "
    print_header
    # 打印前置空格
    $SUNDAY && print_spaces_before $first_day
    $MONDAY && print_spaces_before $((${first_day/0/7}-1))
    week_line=1
    $SUNDAY && lday=6
    $MONDAY && lday=0
    # 打印日期
    for ((day=1; day<=days_in_month; day++)); do
        if [ "$(date -d "$year-$month-$day" +%F)" = "$today" ]; then
            COLOR='\x1b[48;5;4m'
        elif [ "$(date -d "$year-$month-$day" +%F)" = "$preview" ]; then
            COLOR='\x1b[48;5;2m'
        elif [[ "$(date -d "$year-$month-$day +1 day" +%F)" > "$start_date" && "$(date -d "$year-$month-$day" +%F)" < "$medium_date" && "$(date -d "$year-$month-$day" +%F)" != "$today" ]]; then
            COLOR='\x1b[7m'
        elif [[ "$(date -d "$year-$month-$day +1 day" +%F)" > "$medium_date" && "$(date -d "$year-$month-$day" +%F)" < "$end_date" && "$(date -d "$year-$month-$day" +%F)" != "$today" ]];then 
            COLOR='\x1b[48;5;16m'
        else
            COLOR=''
        fi
        # echo | awk '{printf ("'"$(date -d "$year-$month-$day +1 day" +%F)"'">"'"${vdate}"'")?"\x1b[7m%2d\x1b[0m ":"%2d ","'"$day"'"}'
        local current_day_of_week=$(date -d "$year-$month-$day" '+%w')
        if [ $current_day_of_week -eq ${lday} ]; then
            printf "${COLOR}%2d\e[0m\n" $day
            let week_line++
        else
            printf "${COLOR}%2d\e[0m " $day
        fi
    done
    $SUNDAY && print_spaces_after $((lday-last_day_week))
    $MONDAY && print_spaces_after $((7-${last_day_week/0/7}))
    [ "${week_line}" -ne 6 ] && print_spaces_after 7
}

yuanshen ()
{
    #start_date='2023-08-16'
    #major_version=4
    start_date='2024-08-28' # 4.0 5.0 就差 12
    major_version=5
    minor_version=0
    count=0 # 查看当前和后面 n 个版本
    echo '理论：3 周一个小版本，6 周一个大版本，前瞻为 大版本前两周的周五'
    echo '每年：6(周/版本)*9(版本)*7(天/周)=378天   378-(365/366)天=13/12天'

    while true; do
        end_date=$(next_N_day "${start_date}" 42)  # 下个大版本
        if [[ "$(next_N_day "" -42)" < "${start_date}" ]];then
            medium_date=$(next_N_day "${start_date}" 21) # 版本下半
            x_date=$(next_N_day "${start_date}" -12) # 版本前瞻
            declare -gA ysVerDate[${major_version}.${minor_version}]="${x_date}|${start_date}|${medium_date}"
            if [ "${count}" -eq 0 ];then
                if [[ "$(date +%F)" < "${medium_date}" ]];then
                    echo "当前版本为：${major_version}.${minor_version} 上半 ${start_date} ~ $(next_N_day ${start_date} 20)"
                else
                    echo "当前版本为：${major_version}.${minor_version} 下半 ${medium_date} ~ $(next_N_day ${medium_date} 20)"
                fi
                month_list=$(out_month "$start_date" | xargs -ri echo '<(print_month '{}')')
                # print_month 2024 10
                # print_month 2024 11
                echo -e "\x1b[48;5;4m今天\e[0m  \x1b[48;5;2m前瞻\e[0m  \x1b[7m上半\e[0m  \x1b[48;5;16m下半\e[0m"
                eval paste ${month_list}
                printf '%s  %-10s|%-10s|%-10s\n' 'VER' 'preview' 'first' 'second'
            fi
            echo "${major_version}.${minor_version}  ${ysVerDate[${major_version}.${minor_version}]}"
            let count++
        fi
        if [ ${minor_version} -ge 8 ];then
            minor_version=0    # 版本到 8 重置
            let major_version++
        else
            let minor_version++
        fi
        start_date=${end_date}
        [ "${count}" -gt 5 ] && break
    done
}

set_option "$@"
yuanshen
#out_month "$1"
